/*
 * pit.c
 * Project 4
 * Nicole Ang (nang1@asu.edu)
 * Bijan Fakhri (bfakhri@asu.edu)
 * CSE 325: Embedded Microprocessor Systems
 * Spring 2013
 */

#include "pit.h"

int currentTempo;

void pit0_init(){
	//disable while configuring
	MCF_PIT0_PCSR &= ~MCF_PIT_PCSR_EN;
	
	//reload counter when it reaches 0
	MCF_PIT0_PCSR |= MCF_PIT_PCSR_RLD;
	
	//reset interrupt flag
	MCF_PIT0_PCSR |= MCF_PIT_PCSR_PIF;
	
	//enable PIF flag to generate interrupt requests
	MCF_PIT0_PCSR |= MCF_PIT_PCSR_PIE;
	
	//immediately overwrite value in PIT counter
	MCF_PIT0_PCSR |= MCF_PIT_PCSR_OVW;
	
	//stop PIT funciton in debug mode
	MCF_PIT0_PCSR |= MCF_PIT_PCSR_DBG;
	
	//set prescaler
	MCF_PIT0_PCSR |= MCF_PIT_PCSR_PRE(13);
	
	//Initially set timeout period to 1 sec = 60 BPM.
	currentTempo = 60;
	setTempo(60);
	
	//configure INTC to recognize & respond to interrupt requests
	intcr_config(55, 1, 7, pit0_isr);
	
	//enable
	MCF_PIT0_PCSR |= MCF_PIT_PCSR_EN;
}

__declspec(interrupt) void pit0_isr(){
	/* Clear interrupt request flag. */
	MCF_PIT0_PCSR |= MCF_PIT_PCSR_PIF;

	//turn led off
	led_off();
	playNextNote();
}
 
void setTempo(int newBeat){
	//disable while configuring
	MCF_PIT0_PCSR &= ~MCF_PIT_PCSR_EN;
	
	if(newBeat == 0)//set to currentTempo
		newBeat = currentTempo;
		
	//set value of counter
	switch(newBeat){
	case 70: quarterNoteTime = 4184;
		currentTempo = 70;
		break;
	case 80: quarterNoteTime = 3661;
		currentTempo = 80;
		break;
	case 90: quarterNoteTime = 3254;
		currentTempo = 90;
		break;
	case 100: quarterNoteTime = 2929;
		currentTempo = 100;		
		break;	
	case 110: quarterNoteTime = 2662;
		currentTempo = 110;
		break;
	case 120: quarterNoteTime = 2440;
		currentTempo = 120;
		break;
	default: quarterNoteTime = 4882;
		currentTempo = 60;
		break;
	}
	MCF_PIT0_PMR = MCF_PIT_PMR_PM((unsigned short)quarterNoteTime);
	//enable
	MCF_PIT0_PCSR |= MCF_PIT_PCSR_EN;
}

//this changes pit for note duration
//see if can change pwm for note duration
void setDuration(NoteDur dur, unsigned int time){
	//disable while configuring
	MCF_PIT0_PCSR &= ~MCF_PIT_PCSR_EN;
	unsigned int counter = MCF_PIT0_PMR;
	switch(dur){
	case whole: counter = time * 4;
		break;
	case half_dot: counter = time * 3;
		break;
	case half: counter = time * 2;
		break;
	case quarter_dot: counter = (unsigned int)(time);
		break;
	case eighth_dot: counter = (unsigned int)(time * .75);
		break;
	case eighth: counter = (unsigned int)(time / 2);
		break;
	case sixteenth_dot: counter = (unsigned int)(time * 0.375);
		break;
	case sixteenth: counter = (unsigned int)(time / 4);
		break;
	case thirty_secondth_dot: counter = (unsigned int)(time * 0.1875);
		break;
	case thirty_secondth: counter = (unsigned int)(time / 8);
		break;
	case sixty_fourth_dot: counter = (unsigned int)(time * 0.09375); 
		break;
	case sixty_fourth: counter = (unsigned int)(time / 16);
		break;
	default: //quarter note, leave as is
		break;
	}
	
	
	//assign new value to PMR
	MCF_PIT0_PMR = MCF_PIT_PMR_PM((unsigned short)counter);
	//enable
	MCF_PIT0_PCSR |= MCF_PIT_PCSR_EN;
}